<?php

namespace Pro\Support;

use Closure;
use Illuminate\Support\Facades\Log;

class Download
{
    /**
     * 下载文件
     * @param string         $url
     * @param string|Closure $dest
     * @return bool|int
     * @throws \Exception
     */
    public static function downloadFile(string $url, string|Closure $dest): bool|int
    {
        // 使用cURL进行优化下载
        $ch = curl_init();

        // 基本设置
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
        curl_setopt($ch, CURLOPT_MAXREDIRS, 5);

        // 超时设置
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);

        // SSL设置
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

        // HTTP版本和连接优化
        curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);
        curl_setopt($ch, CURLOPT_TCP_KEEPALIVE, 1);
        curl_setopt($ch, CURLOPT_TCP_KEEPIDLE, 120);
        curl_setopt($ch, CURLOPT_TCP_KEEPINTVL, 60);

        // 设置完整的浏览器头信息
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
            'Accept: image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8',
            'Accept-Language: zh-CN,zh;q=0.9,en;q=0.8',
            'Accept-Encoding: gzip, deflate, br',
            'Connection: keep-alive',
            'Upgrade-Insecure-Requests: 1',
            'Sec-Fetch-Dest: image',
            'Sec-Fetch-Mode: no-cors',
            'Sec-Fetch-Site: cross-site',
            'Cache-Control: no-cache',
            'Pragma: no-cache'
        ]);

        // 启用压缩
        curl_setopt($ch, CURLOPT_ENCODING, '');

        // 执行请求
        $content = curl_exec($ch);

        $errorMsg = curl_error($ch);
        $errorNo = curl_errno($ch);
        curl_close($ch);

        if ($errorNo) {
            Log::error("下载文件失败，url:{$url}, errno:{$errorNo}, error:{$errorMsg}");
            throw new \Exception("下载文件失败，url:{$url}, errno:{$errorNo}, error:{$errorMsg}");
        }

        if ($dest instanceof Closure) {//匿名函数
            return $dest($content);
        } else {
            return file_put_contents($dest, $content);
        }
    }
}
